package com.oop.example.work.esport;

import antlr.output.MultiFarLexer;
import com.oop.example.processing.TockenMap;
import com.oop.example.xml.Block;
import com.oop.example.xml.ObjectFactory;
import com.oop.example.xml.Phrase;
import com.oop.example.xml.Phrase.Label;
import com.oop.example.xml.PhraseWithAttribs;
import java.util.ArrayList;
import java.util.List;
import javax.xml.bind.JAXB;
import javax.xml.bind.JAXBElement;

public class LabelInserter {

    private ObjectFactory factory;
    private TockenMap tockenMap;
    private Esp2PortHtmlParser parser;
    List<JAXBElement<?>> elements = new ArrayList<JAXBElement<?>>();
    private boolean hasSenseNum = false;
    private boolean hasSubSenseNum = false;
    boolean someOtherThenLabel = false;

    public void markHasSenseNum() {
        this.hasSenseNum = true;
    }

    public void markHasSubSenseNum() {
        this.hasSubSenseNum = true;
    }

    public LabelInserter(ObjectFactory factory, TockenMap tockenMap, Esp2PortHtmlParser parser) {
        this.factory = factory;
        this.tockenMap = tockenMap;
        this.parser = parser;
    }

    public void markBeforeInsert(int tockenId) {
        if (tockenId == MultiFarLexer.NUMERATION) {
            if (!elements.isEmpty()) {
                for (JAXBElement<?> element : elements) {
                    if (parser.near != null) {
                        parser.near.getNearChildren().remove(element);
                    }
                    if (!parser.getVariantClassifier().getPhraseChildren().contains(element)) {
                        parser.getVariantClassifier().getPhraseChildren().add(element);
                    }
                }
                elements = new ArrayList<JAXBElement<?>>();
            }
            //если есть че, вставляем в классификатор внутри variant
        } else if (tockenId == MultiFarLexer.SUB_NUMERATION) {
            if (!elements.isEmpty()) {
                for (JAXBElement<?> element : elements) {
                    if (parser.near != null) {
                        //System.out.println("remove from near");
                        parser.near.getNearChildren().remove(element);
                    }
                    //System.out.println("remove from variant");
                    parser.getVariantClassifier().getPhraseChildren().remove(element);

                    if (!parser.getSenseClassifier().getPhraseChildren().contains(element)) {
                        //System.out.println("add to SenseClassifier");
                        parser.getSenseClassifier().getPhraseChildren().add(element);
                    }
                }
                elements = new ArrayList<JAXBElement<?>>();
            }
            //если есть че, вставляем в классификатор внутри sense
        } else if (tockenId == MultiFarLexer.DOT
                || tockenId == MultiFarLexer.COLON) {
            elements = new ArrayList<JAXBElement<?>>();
        }
    }

    public void markAfterInsert(int tockenId) {
    }

    public void insertLabel(String label) {
        label = label.replace("<i>{", "").replace("}</i>", "");
        Phrase.Label lab = new Phrase.Label();
        lab.setValue(label);
        JAXBElement<Phrase.Label> partLabel = factory.createEntryHeadingVocablePartLabel(lab);
        insert(partLabel, false);
    }

    public void insertNearLabel(String label) {
        label = label.replace("<i>{", "").replace("}</i>", "");
        Phrase.Label lab = new Phrase.Label();
        lab.setValue(label);
        JAXBElement<Phrase.Label> partLabel = factory.createEntryHeadingVocablePartLabel(lab);
        insert(partLabel, true);
    }

    public void insertText(String txt) {
        Block block = factory.createBlock();
        block.setValue(txt);
        JAXBElement<Block> plus = factory.createEntryHeadingVocablePartSimple(block);
        insert(plus, false);
    }

    public void insertNearText(String txt) {
        Block block = factory.createBlock();
        block.setValue(txt);
        JAXBElement<Block> plus = factory.createEntryHeadingVocablePartSimple(block);
        insert(plus, true);
    }

    private void insert(JAXBElement<?> element, boolean inNear) {
        elements.add(element);
        if (inNear) {
            parser.getNear().getNearChildren().add(element);
        } else {
            if (hasSenseNum || hasSubSenseNum) {
                parser.getVariantClassifier().getPhraseChildren().add(element);
//            } else if (hasSubSenseNum) {
//                Object value = element.getValue();
//                if (value instanceof Label) {
//                    System.out.println("Label " + ((Label) value).getValue());
//                } else if (value instanceof Block){
//                    System.out.println("Block " + ((Block) value).getValue());
//                }
//                parser.getSenseClassifier().getPhraseChildren().add(element);
//                //JAXB.marshal(parser.getEntry(), System.out);
            } else {
                //System.out.println("getSubSenseClassifier");
                parser.getSubSenseClassifier().getPhraseChildren().add(element);
            }
        }
    }
    
    public void postInsert(){
        if (hasSubSenseNum && !hasSenseNum){
            JAXBElement<?> classifire = parser.getVariant().getPronunciationOrClassifierOrTranslation().get(0);
            if (classifire != null && classifire.getValue() instanceof PhraseWithAttribs){
                parser.getVariant().getPronunciationOrClassifierOrTranslation().remove(classifire);
                parser.getSense().getPronunciationOrClassifierOrTranslation().add(0, classifire);
            }
        }
    }
}
